home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
AUTOCAD
/
H107.ZIP
/
WINDXF.ZIP
/
DXFDRAW.C
< prev
next >
Wrap
Text File
|
1990-11-25
|
11KB
|
432 lines
#include <windows.h>
#include <math.h>
#include "windxf.h"
#include <stdlib.h>
#include <stdio.h>
extern HWND GBL_hwnd;
extern HDC mfhdc;
extern HDC GBL_hdc;
typedef struct {
int number;
char marker[80];
} DXF_STATE;
#define NUM_STATES 30
DXF_STATE statetab[] = { 0,"SECTION", /* Section Begin 1 */
2,"HEADER", /* Header 2 */
0,"ENDSEC", /* End Section 3 */
2,"TABLES", /* Tables section 4 */
0,"TABLE", /* Table Begin 5 */
2,"VPORT", /* Viewport 6 */
70,"#", /* 70 with a count 7 */
0,"ENDTAB", /* End of table 8 */
9,"$EXTMIN", /* Min Extents 9 */
9,"$EXTMAX", /* Max Extents 10 */
10,"#", /* X coord 11 */
20,"#", /* Y coord 12 */
2,"ENTITIES", /* Entities 13 */
11,"#", /* X2 coord 14 */
21,"#", /* Y2 coord 15 */
0,"LINE", /* Line Entity 16 */
0,"ATTDEF", /* Attribute Def 17 */
8, "#", /* Layer Name 18 */
40,"#", /* Height 19 */
1, "#", /* Primary Text 20 */
2, "#", /* Name 21 */
3, "#", /* Other Text 22 */
50,"#", /* Angle 23 */
51,"#", /* Angle 24 */
0, "ARC", /* Arc 25 */
0, "POLYLINE",/* Polyline 26 */
0, "VERTEX", /* Vertex 27 */
0, "SEQEND", /* End Sequence 28 */
66, "#", /* Entities Follow 29 */
41, "#", /* End Width 30 */
};
typedef enum {
NUMBER,
MARKER,
} READ_STATE;
READ_STATE curstate = NUMBER;
char layer[256], heightstr[256], textstr[256];
double wx1, wy1, wx2, wy2;
int logextx, logexty;
int
ReadDXF(dxfname)
char * dxfname;
{
int fd;
char line1[256], line2[256];
int st;
double x, y;
int color;
char msg[256];
int xi,yi;
int lx, ly;
int section_active = 0;
int header_active = 0;
int entities_active = 0;
int tables_active = 0;
int table_start = 0;
int polyline_count = 0;
double height, radius, st_ang, end_ang;
MSG msg1;
fd = _lopen(dxfname, OF_READ);
while (1)
{
PeekMessage(&msg1, GBL_hwnd,(WORD)0,(WORD)0,PM_NOREMOVE);
if (getline(line1, 256, fd) == NULL)
break;
if (getline(line2, 256, fd) == NULL)
break;
st = dxfstate(line1, line2);
switch(st)
{
case 1: /* Section */
section_active = 1;
break;
case 2: /* Header */
header_active = 1;
break;
case 3: /* End Section */
section_active = 0;
/* Whatever section was active, shut it down */
if (header_active)
header_active = 0;
else
if (entities_active)
entities_active = 0;
else
if (tables_active)
tables_active = 0;
break;
case 4: /* Tables Active */
tables_active = 1;
break;
case 5: /* Table */
table_start = 1;
break;
case 8: /* End table */
table_start = 0;
break;
case 9: /* Min Extents */
get_followxyfloat(fd, &wx1, &wy1);
break;
case 10: /* Max Extents */
get_followxyfloat(fd, &wx2, &wy2);
color = 7;
/* Now we're ready to set our world coords.
Adjust the smaller of the axis to form
a square world coordinate system */
if ( (wy2 - wy1) > (wx2 - wx1) )
{
wx2 += (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
wx1 -= (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
}
else
{
wy2 += (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
wy1 -= (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
}
break;
case 13: /* Entities */
entities_active = 1;
break;
case 16: /* Line Entities */
if (entities_active)
{
get_followxyfloat(fd, &x, &y);
MapUsertoLog(x,y,&lx,&ly);
MoveTo(GBL_hdc, lx, ly);
MoveTo(mfhdc, lx, ly);
get_followxyfloat(fd, &x, &y);
MapUsertoLog(x,y,&lx,&ly);
LineTo(GBL_hdc, lx, ly);
LineTo(mfhdc, lx, ly);
}
break;
case 17: /* Attribute Def */
get_followline(fd, 18, layer);
get_followxyfloat(fd, &x, &y);
get_followline(fd, 19, heightstr);
height = atof(heightstr);
get_followline(fd, 20, textstr);
break;
case 25: /* Arc */
get_followarc(fd, &x,&y,&radius,&st_ang,&end_ang);
/* MS Windows doesn't support an arc the way DXF does,
so we'll leave this one for a future version */
/* movabs(&x,&y);
arc(&radius,&end_ang,&st_ang); */
break;
case 26: /* Polyline */
if (entities_active)
{
get_followline(fd, 18, textstr);
get_followline(fd, 29, textstr);
/* Polyline is justing setting us up to read
vertices */
polyline_count = 0;
}
break;
case 27: /* Vertex */
if (entities_active)
{
get_followxyfloat(fd, &x, &y);
MapUsertoLog(x,y,&lx,&ly);
if (polyline_count==0)
{
/* If this is the first vertex, move to it */
MoveTo(GBL_hdc, lx, ly);
MoveTo(mfhdc, lx, ly);
}
else
{
/* Line to subsequent vertices */
LineTo(GBL_hdc, lx, ly);
LineTo(mfhdc, lx, ly);
}
polyline_count++;
}
break;
case 28: /* Sequence end */
if (entities_active)
{
if (polyline_count > 0)
polyline_count = 0;
}
break;
} /* end of switch */
} /* end of while(1) */
_lclose(fd);
return 1;
}
int dxfstate(line1, line2)
char * line1;
char * line2;
{
int ctr;
int num;
int l;
num = atoi(line1);
l = lstrlen(line2);
for (ctr=0; ctr < NUM_STATES; ctr++)
{
if ( (statetab[ctr].number == num) &&
(!lstrcmp(statetab[ctr].marker,line2)))
return ctr+1;
if ( (statetab[ctr].number == num) &&
(!lstrcmp(statetab[ctr].marker,"#")))
return ctr+1;
}
return -1;
}
int
get_followxyfloat(fd, x, y)
int fd;
double * x;
double * y;
{
long pos;
int ctr, st2;
char line1[256], line2[256];
double p1, p2;
char msg[256];
pos = _llseek(fd,0L,1);
ctr = 0;
while (ctr < 2)
{
getline(line1, 256, fd);
getline(line2, 256, fd);
st2 = dxfstate(line1, line2);
if ( (st2 == -1) || (st2 == 18) )
continue;
if ( (st2 == 11) || (st2 == 14) )
{
p1 = atof(line2);
*x = p1;
ctr++;
continue;
}
if ( (st2 == 12) || (st2 == 15) )
{
p2 = atof(line2);
*y = p2;
ctr++;
continue;
}
_llseek(fd, pos, 0);
}
return 1;
}
int
get_followline(fd, st, line)
int fd;
int st;
char * line;
{
long pos;
int st2;
char line1[256], line2[256];
pos = _llseek(fd,0L,1);
while (1)
{
getline(line1, 256, fd);
getline(line2, 256, fd);
st2 = dxfstate(line1, line2);
if (st2 == -1)
continue;
if (st2 == st)
{
lstrcpy(line, line2);
break;
}
_llseek(fd, pos, 0);
}
return 1;
}
int
get_followarc(fd, x, y, radius, st_ang, end_ang)
int fd;
double * x;
double * y;
double * radius;
double * st_ang;
double * end_ang;
{
long pos;
int ctr, st2;
char line1[256], line2[256];
pos = _llseek(fd,0L,1);
ctr = 0;
while (ctr < 5)
{
getline(line1, 256, fd);
getline(line2, 256, fd);
st2 = dxfstate(line1, line2);
if ( (st2 == -1) || (st2 == 18) )
continue;
if ( (st2 == 11) || (st2 == 14) )
{
*x = atof(line2);
ctr++;
continue;
}
if ( (st2 == 12) || (st2 == 15) )
{
*y = atof(line2);
ctr++;
continue;
}
if ( st2 == 19 )
{
*radius = atof(line2);
ctr++;
continue;
}
if ( st2 == 23 )
{
*st_ang = atof(line2);
ctr++;
continue;
}
if ( st2 == 24 )
{
*end_ang = atof(line2);
ctr++;
continue;
}
_llseek(fd, pos, 0);
}
return 1;
}
/* Windows doesn't support fgets, so we have to write
our own binary, unbuffered version. This program could
be greatly enhanced by implementing a look ahead buffer
here */
int getline(line, lim, fd)
char * line;
int lim;
int fd;
{
int ctr;
int nread;
long backup;
long newpos;
nread = _lread(fd, line, lim-1);
if (nread < lim-1)
{
return 0;
}
for (ctr=0; ctr < lim-1; ctr++)
if ( (line[ctr] == (char)13) &&
(line[ctr+1] == (char)10) )
{
line[ctr] = (char)NULL;
backup = ctr - lim + 3;
newpos = _llseek(fd, (long)backup, 1);
return 1;
}
line[lim-1] = '\0';
/* Should never get here... */
MessageBox(GBL_hwnd, "Didn't hit loop", (LPSTR) NULL, MB_OK);
}
/* maps user coordinates to logical device coordinates */
int
MapUsertoLog(x,y,lx,ly)
double x;
double y;
int * lx;
int * ly;
{
*lx = (int) (((x-wx1)/(wx2-wx1)) * (double)1000);
*ly = (int) (((y-wy1)/(wy2-wy1)) * (double)1000);
*ly = 1000 - *ly;
}